package com.ddwl.gate.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ddwl.common.constant.GateEnum;
import com.ddwl.common.constant.MobileConfigEnum;
import com.ddwl.common.constant.OrderTypeEnum;
import com.ddwl.common.constant.RabbitMqConstants;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.FundsApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.gate.constant.MobileConfigConstant;
import com.ddwl.gate.dao.MobileRechargeRecordDao;
import com.ddwl.gate.feign.BoHuanClient;
import com.ddwl.gate.feign.JDClient;
import com.ddwl.gate.model.BohuanCallRecord;
import com.ddwl.gate.model.MobileNumInfo;
import com.ddwl.gate.model.MobileRechargeConfig;
import com.ddwl.gate.model.MobileRechargeRecord;
import com.ddwl.gate.util.boHuan.BoHuanRechargeUtil;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.funds.FundsPaymentBo;
import com.ddwl.schema.bo.funds.OrderRefundCreBo;
import com.ddwl.schema.bo.funds.PayOrderCreBo;
import com.ddwl.schema.bo.gate.MobileRechargeBo;
import com.ddwl.schema.bo.gate.MobileRechargeRecordBo;
import com.ddwl.schema.bo.gate.MobileRechargeRecordPageBo;
import com.ddwl.schema.bo.gate.RechargeRefundBo;
import com.ddwl.schema.util.DateUtil;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.base.RestVo;
import com.ddwl.schema.vo.funds.OrderPaymentVo;
import com.ddwl.schema.vo.funds.OrderRefundsVo;
import com.ddwl.schema.vo.gate.MobileRechargeRecordVo;
import com.ddwl.schema.vo.order.StatisticsAmountVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author hemiaojun
 * @Date 2020/9/23 9:27
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MobileRechargeRecordService {

    @Value("${spring.profiles.active}")
    private String profile;

    private final MobileRechargeRecordDao mobileRechargeRecordDao;
    private final MobileRechargeConfigService mobileRechargeConfigService;
    private final MobileNumInfoService mobileNumInfoService;
    private final BohuanCallRecordService bohuanCallRecordService;
    private final FundsApi fundsApi;
    private final BoHuanClient boHuanClient;
    private final RabbitTemplate rabbitTemplate;
    private final JDClient jdClient;
    private final DictionaryService dictionaryService;

    public PageVo<MobileRechargeRecordVo> page(PageBo<MobileRechargeRecordPageBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<MobileRechargeRecord> info = new PageInfo(mobileRechargeRecordDao.getList(pageBo.getParam()));
        List<MobileRechargeRecordVo> list = BeanConverUtils.convertBeanList(info.getList(), MobileRechargeRecordVo.class);
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), list);
    }

    public List<StatisticsAmountVo> getAmount(MobileRechargeRecordPageBo pageBo) {
        List<StatisticsAmountVo> list = mobileRechargeRecordDao.getAmount(pageBo);
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    public String callBackNotify(Map<String, String> map) throws Exception {
        log.info("method callBackNotify param {}", JSON.toJSONString(map));
        String result = "ok";
        Boolean flag = BoHuanRechargeUtil.CheckSign(map);
        log.info("flag {}", flag);
        if (!flag) {
            return "Incorrect signature";
        }
        String szOrderId = map.get("szOrderId");
        BohuanCallRecord bcr = bohuanCallRecordService.queryBySerialnoAndType(szOrderId, MobileConfigEnum.BohuanCallEnum.BUY.getType());
        if (null != bcr) {
            MobileRechargeRecord mrr = mobileRechargeRecordDao.selectByPrimaryKey(bcr.getRechargeId());
            BohuanCallRecord bohuanCallRecord = BeanConverUtils.convertBean(mrr, BohuanCallRecord.class);
            bohuanCallRecord.setRechargeId(mrr.getId());
            addBohuanCallBackRecord(map, bohuanCallRecord, MobileConfigEnum.BohuanCallEnum.NOTIFY);

            String status = map.get("nFlag");
            if (!MobileConfigEnum.RechargeEnum.SUCCESS.getCode().equals(status)) {
//                if (MobileConfigEnum.RechargeEnum.ACCEPTED.getCode().equals(mrr.getStatus()) && MobileConfigConstant.NOT_TRY_AGAIN.equals(bcr.getTryAgain())) {
//                    tryAgain(mrr);
//                }else{
                updateMobileRechargeRecord(map, mrr.getId());
                //失败自动退款
                autoRefund(mrr.getId());
//                }
            }
            if (MobileConfigEnum.RechargeEnum.SUCCESS.getCode().equals(status)) {
                if (MobileConfigConstant.NOT_TRY_AGAIN.equals(bcr.getTryAgain())) {
                    MobileRechargeConfig mrc = mobileRechargeConfigService.getByItemId(mrr.getItemId());
                    addMobileNumInfo(mrr.getMobile(), null, null, null, new Byte(mrc.getOperator()), null);
                }
                updateMobileRechargeRecord(map, mrr.getId());
            }
        }
        return result;
    }

    private void addBohuanCallBackRecord(Map<String, String> map, BohuanCallRecord bohuanCallRecord, MobileConfigEnum.BohuanCallEnum bohuanCallEnum) {
        bohuanCallRecord.setId(UUIDGenerator.getShortUUID());
        bohuanCallRecord.setCallType(bohuanCallEnum.getType());
        bohuanCallRecord.setCallName(bohuanCallEnum.getName());
        bohuanCallRecord.setBizOrderId(map.get("szOrderId"));
        bohuanCallRecord.setThirdStatus(map.get("nFlag"));
        bohuanCallRecord.setMobile(map.get("szPhoneNum"));
        bohuanCallRecord.setSalePrice(new BigDecimal(map.get("fSalePrice")).setScale(4));
        bohuanCallRecordService.add(bohuanCallRecord);
    }

    private void updateMobileRechargeRecord(Map<String, String> map, String id) {
        MobileRechargeRecord entity = new MobileRechargeRecord();
        String nFlag = map.get("nFlag");
        String szOrderId = map.get("szOrderId");
        entity.setId(id);
        entity.setBizOrderId(szOrderId);
        entity.setStatus(Integer.parseInt(nFlag));
        entity.setDescription(MobileConfigEnum.RechargeEnum.getDescByCode(nFlag));
        mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
    }

    private void tryAgain(MobileRechargeRecord mrr) throws Exception {
        JSONObject jsonObject = getAndAddMobileNumInfo(mrr.getMobile());
        if (null != jsonObject) {
            String provider = jsonObject.getString("provider");
            if (StrUtil.isNotEmpty(provider)) {
                Byte operator = MobileConfigEnum.JDOperatorMatchEnum.getSystemCode(provider);
                String serialno = UUIDGenerator.getTimeUUID();
                mrr.setSerialno(serialno);
                saveReturnInfo(mrr, operator, MobileConfigConstant.TRY_AGAIN);
            }
        }
    }

    private JSONObject getAndAddMobileNumInfo(String mobile) {
        JSONObject jsonObject = searchPhoneFromJD(mobile);
        if (null != jsonObject) {
            String area = jsonObject.getString("area");
            String areaName = jsonObject.getString("areaName");
            String provider = jsonObject.getString("provider");
            String providerName = jsonObject.getString("providerName");
            if (StrUtil.isNotEmpty(provider)) {
                addMobileNumInfo(mobile, area, areaName, provider, null, providerName);
            }
        }
        return jsonObject;
    }

    private void addMobileNumInfo(String mobile, String area, String areaName, String provider, Byte operator, String providerName) {
        MobileNumInfo mobileNumInfo = new MobileNumInfo();
        mobileNumInfo.setMobile(mobile);
        mobileNumInfo.setAreaCode(area);
        mobileNumInfo.setAreaName(areaName);
        if (null != operator) {
            mobileNumInfo.setOperator(operator);
        } else {
            mobileNumInfo.setOperator(MobileConfigEnum.JDOperatorMatchEnum.getSystemCode(provider));
        }
        mobileNumInfo.setOperatorName(providerName);
        mobileNumInfoService.add(mobileNumInfo);
    }

    private JSONObject searchPhoneFromJD(String mobile) {
        try {
            RestTemplate restTemplate = new RestTemplate();
            String jdResult = restTemplate.getForObject(MobileConfigConstant.JD_SEARCH_PHONE, String.class, mobile);
            return analyze(jdResult);
        } catch (Exception e) {
            log.error("jd searchPhone error {}", e);
        }
        return null;
    }

    /**
     * 下单
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public MobileRechargeRecordVo recharge(MobileRechargeRecordBo bo) {
        MobileRechargeRecord entity = BeanConverUtils.convertBean(bo, MobileRechargeRecord.class);
        MobileRechargeConfig mrc = mobileRechargeConfigService.getByItemId(bo.getItemId());
        ParamException.isNull(mrc, "该面额商品不存在");
        String serialno = UUIDGenerator.getTimeUUID();
        OrderPaymentVo orderPayVo = createPayOrder(bo, mrc.getPrice(), serialno);
        ParamException.isNull(orderPayVo, "下单失败");
        entity.setPayOrderNo(orderPayVo.getId());
        entity.setSerialno(serialno);
        entity.setFacePrice(mrc.getFacePrice());
        entity.setPrice(mrc.getPrice());
        entity.setStatus(MobileConfigEnum.RechargeEnum.ORDER_CRE.getCode());
        entity.setId(UUIDGenerator.getShortUUID());
        mobileRechargeRecordDao.insert(entity);
        rabbitTemplate.convertAndSend(RabbitMqConstants.MOBILE_RECHARGE_ORDER_TIMEOUT_DL_EXCHANGE, RabbitMqConstants.MOBILE_RECHARGE_ORDER_TIMEOUT_DL_QUEUE, entity.getId());
        return BeanConverUtils.convertBean(entity, MobileRechargeRecordVo.class);
    }

    /**
     * 支付
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public RestVo<String> pay(MobileRechargeBo bo) {
        MobileRechargeRecord entity = mobileRechargeRecordDao.queryBySerialno(bo.getOrderId());
        ParamException.isNull(entity, "该订单不存在");
        ParamException.isTrue(MobileConfigEnum.RechargeEnum.CLOSED.getCode().equals(entity.getStatus()), "该订单已关闭");
        ParamException.isTrue(!MobileConfigEnum.RechargeEnum.ORDER_CRE.getCode().equals(entity.getStatus()), "请勿重复支付");
        updatePayType(entity.getId(), bo.getPayType());
        FundsPaymentBo paymentBo = BeanConverUtils.convertBean(bo, FundsPaymentBo.class);
        log.info("fundsApi.payment param {}", JSON.toJSONString(paymentBo));
        RestVo<String> restVo = fundsApi.payment(paymentBo);
        log.info("fundsApi.payment result {}", JSON.toJSONString(restVo));
        return restVo;
    }

    private void updatePayType(String id, Integer payType) {
        MobileRechargeRecord update = new MobileRechargeRecord();
        update.setId(id);
        update.setPayType(payType);
        mobileRechargeRecordDao.updateByPrimaryKeySelective(update);
    }

    private OrderPaymentVo createPayOrder(MobileRechargeRecordBo bo, BigDecimal price, String serialno) {
        PayOrderCreBo payOrderCreBo = BeanConverUtils.convertBean(bo, PayOrderCreBo.class);
        payOrderCreBo.setOrderId(serialno);
        payOrderCreBo.setOrderType(OrderTypeEnum.moreCredit.getCode());
        payOrderCreBo.setTotalAmount(price);
        payOrderCreBo.setExpirationTime(DateUtil.getTimeAfterSomeMinute(15));
        payOrderCreBo.setNotifyMethod(RabbitMqConstants.MOBILE_RECHARGE_NOTIFY_QUEUE);
        log.info("fundsApi.create param {}", JSON.toJSONString(payOrderCreBo));
        RestVo<OrderPaymentVo> orderPayVoRestVo = fundsApi.create(payOrderCreBo);
        log.info("fundsApi.create result {}", JSON.toJSONString(orderPayVoRestVo));
        if (null != orderPayVoRestVo && null != orderPayVoRestVo.getResult()) {
            return orderPayVoRestVo.getResult();
        }
        return null;
    }

    /**
     * 支付成功后回调用
     *
     * @param orderPayVo
     */
    public void orderPayCallBack(OrderPaymentVo orderPayVo) throws Exception {
        log.info("method orderPayCallBack param {}", JSON.toJSONString(orderPayVo));
        MobileRechargeRecord mrr = mobileRechargeRecordDao.getBySerialno(orderPayVo.getOrderId());
        ParamException.isNull(mrr, "充值订单不存在");
        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        if (MobileConfigEnum.PayStatus.FAIL.getCode().equals(orderPayVo.getTradeStatus())) {
            entity.setStatus(MobileConfigEnum.RechargeEnum.PAY_FAIL.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.PAY_FAIL.getDesc());
            mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
            return;
        }
        if (MobileConfigEnum.PayStatus.SUCCEED.getCode().equals(orderPayVo.getTradeStatus())) {
            entity.setStatus(MobileConfigEnum.RechargeEnum.RECHARGING.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.RECHARGING.getDesc());
            mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        }
        MobileRechargeConfig mrc = mobileRechargeConfigService.getByItemId(mrr.getItemId());
        saveReturnInfo(mrr, mrc.getOperator(), MobileConfigConstant.NOT_TRY_AGAIN);
    }

    private void saveReturnInfo(MobileRechargeRecord mrr, Byte operator, Integer tryAgain) throws Exception {
        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        HashMap<String, String> map = fillParam(mrr, operator);
        JSONObject obj = invokeBohuanBuy(map);
        String status = obj.getString("szRtnCode");
        Integer code = obj.getInteger("nRtn");
        String desc = obj.getString("szRtnCode");
        String bizOrderId = obj.getString("szOrderId");
        BigDecimal salePrice = obj.getBigDecimal("fSalePrice");
        addBohuanCallRecord(mrr, bizOrderId, salePrice, code.toString(), status, desc, tryAgain, MobileConfigEnum.BohuanCallEnum.BUY);
        if (MobileConfigConstant.SUCCESS_CODE.equals(code)) {
            entity.setStatus(MobileConfigEnum.RechargeEnum.ACCEPTED.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.ACCEPTED.getDesc());
        } else {
            entity.setStatus(MobileConfigEnum.RechargeEnum.ACCEPT_FAIL.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.ACCEPT_FAIL.getDesc());
        }
        entity.setBizOrderId(bizOrderId);
        entity.setSalePrice(salePrice);
        mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        if (!MobileConfigConstant.SUCCESS_CODE.equals(code)) {
            if (MobileConfigConstant.OPERATOR_MISMATCH_CODE.equals(code) && MobileConfigConstant.NOT_TRY_AGAIN.equals(tryAgain)) {
                tryAgain(mrr);
            } else {
                //失败自动退款
                autoRefund(mrr.getId());
            }
        }
    }

    private void addBohuanCallRecord(MobileRechargeRecord mrr, String bizOrderId, BigDecimal salePrice, String code, String status, String desc, Integer tryAgain, MobileConfigEnum.BohuanCallEnum bohuanCallEnum) {
        BohuanCallRecord bcr = new BohuanCallRecord();
        bcr.setMobile(mrr.getMobile());
        bcr.setRechargeId(mrr.getId());
        bcr.setSerialno(mrr.getSerialno());
        bcr.setItemId(mrr.getItemId());
        bcr.setCallType(bohuanCallEnum.getType());
        bcr.setCallName(bohuanCallEnum.getName());
        bcr.setBizOrderId(bizOrderId);
        bcr.setSalePrice(salePrice);
        bcr.setThirdCode(code);
        bcr.setThirdStatus(status);
        bcr.setThirdDesc(desc);
        bcr.setTryAgain(tryAgain);
        bohuanCallRecordService.add(bcr);
    }

    private JSONObject invokeBohuanBuy(HashMap<String, String> map) {
        log.info("bohuan buy param {}", JSON.toJSONString(map));
        String result = boHuanClient.recharge(map);
        log.info("bohuan buy result {}", result);
        return analyze(result);
    }

    private JSONObject analyze(String result) {
        return JSONObject.parseObject(result);
    }

    private HashMap<String, String> fillParam(MobileRechargeRecord mrr, Byte operator) throws Exception {
        HashMap<String, String> map = new HashMap<>(16);
        map.put("nMoney", mrr.getFacePrice() + "");
        map.put("szPhoneNum", mrr.getMobile());
        map.put("szOrderId", mrr.getSerialno());
        map.put("nSortType", operator.toString());
        map.put("nProductClass", "1");
        map.put("nProductType", "1");
        map.put("szTimeStamp", DateUtil.formatDate(mrr.getGmtCreated(), DateUtil.DATE_TIME_FORMAT));
        if ("prod".equals(profile)) {
            map.put("szNotifyUrl", MobileConfigConstant.NOTIFY_URL);
        } else {
            map.put("szNotifyUrl", MobileConfigConstant.NOTIFY_URL_TEST);
        }
        BoHuanRechargeUtil.submitOrderAddSign(map);
        return map;
    }

    public MobileRechargeRecordVo cancel(String id) {
        MobileRechargeRecord mrr = mobileRechargeRecordDao.selectByPrimaryKey(id);
        ParamException.isNull(mrr, "该订单不存在");
        ParamException.isFalse(MobileConfigEnum.RechargeEnum.ORDER_CRE.getCode().equals(mrr.getStatus()), "该订单已支付成功，请耐心等待");
        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        entity.setStatus(MobileConfigEnum.RechargeEnum.CLOSED.getCode());
        entity.setDescription(MobileConfigEnum.RechargeEnum.CLOSED.getDesc());
        mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        mrr.setStatus(MobileConfigEnum.RechargeEnum.CLOSED.getCode());
        return BeanConverUtils.convertBean(mrr, MobileRechargeRecordVo.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public MobileRechargeRecordVo refund(RechargeRefundBo bo) {
        MobileRechargeRecord mrr = mobileRechargeRecordDao.selectByPrimaryKey(bo.getRechargeRecordId());
        ParamException.isNull(mrr, "没有找到该订单");
        ParamException.isTrue(!(MobileConfigEnum.RechargeEnum.FAIL.getCode().equals(mrr.getStatus())
                || MobileConfigEnum.RechargeEnum.REFUND_FAIL.getCode().equals(mrr.getStatus())
                || MobileConfigEnum.RechargeEnum.ACCEPT_FAIL.getCode().equals(mrr.getStatus())), "该订单不允许退款");
        OrderRefundsVo orderRefundsVo = createRefundOrder(bo, mrr);
        ParamException.isNull(orderRefundsVo, "退款出错");
        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        if (MobileConfigEnum.PayStatus.FAIL.getCode().equals(orderRefundsVo.getStatus())) {
            fillStatus(mrr, entity, MobileConfigEnum.RechargeEnum.REFUND_FAIL);
        } else if (MobileConfigEnum.PayStatus.SUCCEED.getCode().equals(orderRefundsVo.getStatus())) {
            fillStatus(mrr, entity, MobileConfigEnum.RechargeEnum.REFUND_SUCCESS);
        } else {
            fillStatus(mrr, entity, MobileConfigEnum.RechargeEnum.REFUNDING);
        }
        mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        return BeanConverUtils.convertBean(mrr, MobileRechargeRecordVo.class);
    }

    private void fillStatus(MobileRechargeRecord mrr, MobileRechargeRecord entity, MobileConfigEnum.RechargeEnum rechargeEnum) {
        entity.setStatus(rechargeEnum.getCode());
        entity.setDescription(rechargeEnum.getDesc());
        mrr.setStatus(rechargeEnum.getCode());
        mrr.setDescription(rechargeEnum.getDesc());
    }

    private OrderRefundsVo createRefundOrder(RechargeRefundBo bo, MobileRechargeRecord mrr) {
        OrderRefundCreBo creBo = new OrderRefundCreBo();
        creBo.setOperatorId(bo.getOperatorId());
        creBo.setOperatorName(bo.getOperatorName());
        creBo.setOrderId(mrr.getSerialno());
        creBo.setBizRefundsNo(mrr.getPayOrderNo());
        creBo.setRefundAmount(mrr.getPrice());
        creBo.setNotifyMethod(RabbitMqConstants.MOBILE_RECHARGE_REFUND_NOTIFY_QUEUE);
        log.info("fundsApi.refundsCre param {}", JSON.toJSONString(creBo));
        RestVo<OrderRefundsVo> restVo = fundsApi.refundsCre(creBo);
        log.info("fundsApi.refundsCre result {}", JSON.toJSONString(restVo));
        if (null != restVo && null != restVo.getResult()) {
            return restVo.getResult();
        }
        return null;
    }

    /**
     * 退款回调
     *
     * @param vo
     */
    @Transactional(rollbackFor = Exception.class)
    public void orderRefundCallBack(OrderRefundsVo vo) {
        log.info("method orderRefundCallBack param: [{}]", JSON.toJSONString(vo));
        MobileRechargeRecord mrr = mobileRechargeRecordDao.getBySerialno(vo.getOrderNo());
        ParamException.isNull(mrr, "没有找到该订单");

        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        if (MobileConfigEnum.PayStatus.FAIL.getCode().equals(vo.getStatus())) {
            log.info("status fail: [{}]", vo.getStatus());
            entity.setStatus(MobileConfigEnum.RechargeEnum.REFUND_FAIL.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.REFUND_FAIL.getDesc());
            mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        }
        if (MobileConfigEnum.PayStatus.SUCCEED.getCode().equals(vo.getStatus())) {
            log.info("status success: [{}]", vo.getStatus());
            entity.setStatus(MobileConfigEnum.RechargeEnum.REFUND_SUCCESS.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.REFUND_SUCCESS.getDesc());
            mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        }
    }

    public MobileRechargeRecordVo orderStatus(String id) throws Exception {
        MobileRechargeRecord mrr = mobileRechargeRecordDao.selectByPrimaryKey(id);
        HashMap<String, String> map = new HashMap<>(16);
        map.put("szOrderId", mrr.getSerialno());
        JSONObject obj = invokeBohuanQueryOrder(map);
        String status = obj.getString("szRtnCode");
        String szOrderId = obj.getString("szOrderId");
        Integer code = obj.getInteger("nRtn");
        BigDecimal salePrice = obj.getBigDecimal("fSalePrice");
        addBohuanCallRecord(mrr, szOrderId, salePrice, code + "", status, status, MobileConfigConstant.NOT_TRY_AGAIN, MobileConfigEnum.BohuanCallEnum.ORDER);

        MobileRechargeRecord entity = new MobileRechargeRecord();
        entity.setId(mrr.getId());
        entity.setStatus(code);
        mrr.setStatus(code);
        if (new Integer(5012).equals(code)) {
            entity.setDescription("充值成功");
            mrr.setDescription("充值成功");
        } else {
            entity.setDescription("充值失败");
            mrr.setDescription("充值失败");
        }
        mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        return BeanConverUtils.convertBean(mrr, MobileRechargeRecordVo.class);
    }

    private JSONObject invokeBohuanQueryOrder(HashMap<String, String> map) throws Exception {
        BoHuanRechargeUtil.queryOrderAddSign(map);
        log.info("bohuan queryOrder param {}", JSON.toJSONString(map));
        String result = boHuanClient.queryOrder(map);
        log.info("bohuan queryOrder result {}", result);
        return analyze(result);
    }

    private void autoRefund(String rechargeRecordId) {
        String arc = dictionaryService.getSettingVal(GateEnum.DictionaryTag.TAG_SYSTEM.name(), GateEnum.DictionaryField.AUTO_REFUND.name());
        if ("true".equals(arc)) {
            RechargeRefundBo bo = new RechargeRefundBo();
            bo.setRechargeRecordId(rechargeRecordId);
            bo.setOperatorId("system");
            bo.setOperatorName("系统自动退款");
            refund(bo);
        }
    }

    public void payTimeOutProcess(String id) {
        MobileRechargeRecord mrr = mobileRechargeRecordDao.selectByPrimaryKey(id);
        if (MobileConfigEnum.RechargeEnum.ORDER_CRE.getCode().equals(mrr.getStatus())) {
            MobileRechargeRecord entity = new MobileRechargeRecord();
            entity.setId(mrr.getId());
            entity.setStatus(MobileConfigEnum.RechargeEnum.CLOSED.getCode());
            entity.setDescription(MobileConfigEnum.RechargeEnum.CLOSED.getDesc());
            mobileRechargeRecordDao.updateByPrimaryKeySelective(entity);
        }
    }

    public String jdPhone(String mobile) {
        RestTemplate restTemplate = new RestTemplate();
        String jdResult = restTemplate.getForObject(MobileConfigConstant.JD_SEARCH_PHONE, String.class, mobile);
        jdClient.searchPhone(mobile);
        return jdResult;
    }

    public void changeId() {
        List<MobileRechargeRecord> list = mobileRechargeRecordDao.getAll();
        if (!CollectionUtils.isEmpty(list)) {
            Map<String, String> map = new HashMap<>();
            for (MobileRechargeRecord mrr : list) {
                String id = mrr.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                mobileRechargeRecordDao.changeId(map);
                bohuanCallRecordService.changeRechargeRecordId(map);
            }
        }

        List<BohuanCallRecord> callRecords = bohuanCallRecordService.getAll();
        if (!CollectionUtils.isEmpty(callRecords)) {
            Map<String, String> map = new HashMap<>();
            for (BohuanCallRecord bcr : callRecords) {
                String id = bcr.getId();
                if (id.length() == 11) {
                    long longId = UUIDGenerator.reverseShortUUID(id);
                    map.put(id, String.valueOf(longId));
                }
            }
            if (!CollectionUtils.isEmpty(map)) {
                bohuanCallRecordService.changeId(map);
            }
        }
    }
}
